//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_GUI_OBJECT_FACTORY_H
#define _UX_GUI_OBJECT_FACTORY_H

#include "GUIBase.h"

namespace Engine
{
namespace GUI
{

	//
	// GUI Object Factory
	//

	class _EXPORT_ CGUIObjectFactory : public CEngBaseObject
	{
		friend class CoreSystems::CObjectManager;

	public:
		struct TGUIObjectCreateParams
		{
			// types
			struct TWidget
			{
				IGUIBaseObject	*pScreen;
				IGUIBaseObject	*pParent;
			};

			struct TWidgetStyle
			{
				IGUIBaseObject	*pScreen;
			};

			union UData
			{
				TWidget			sWidget;
				TWidgetStyle	sStyle;
			};


			// values
			e_gui_object::type	eType;
			UData				sData;


			// methods
			TGUIObjectCreateParams(): eType(e_gui_object::UNKNOWN)	{ memset( &sData, 0, sizeof(sData) ); }
		};

		typedef bool (CALLBACK *PCreateGUIObjectProc_t)(const TGUIObjectCreateParams &, IGUIBaseObject *&);

	private:
		struct TWidgetType
		{
			PCreateGUIObjectProc_t	pProc;
			string					sTypeName;
			///
			TWidgetType(): pProc(nullfunc) {}
			TWidgetType(PCreateGUIObjectProc_t proc, const string &type): pProc(proc), sTypeName(type) {}
		};

		struct TWidgetStyleType
		{
			PCreateGUIObjectProc_t	pProc;
			string					sTypeName;
			///
			TWidgetStyleType(): pProc(nullfunc) {}
			TWidgetStyleType(PCreateGUIObjectProc_t proc, const string &type): pProc(proc), sTypeName(type) {}
		};
		
		struct TScreenType
		{
			array< TWidgetType >		aWidgetTypes;
			array< TWidgetStyleType >	aStyleTypes;
			PCreateGUIObjectProc_t		pProc;
			string						sTypeName;
			///
			TScreenType(): pProc(nullfunc) {}
			TScreenType(PCreateGUIObjectProc_t proc, const string &type): pProc(proc), sTypeName(type) {}
		};


	private:
		array< TScreenType >	_aGUIScreenTypes;

	protected:
		CGUIObjectFactory();
		~CGUIObjectFactory();

		bool  Init();
		bool _GetScreen(const string &sTypeName, TScreenType *&pType);
		
		// CEngBaseObject //
		virtual void Release();

	public:
		bool CreateWidget(IGUIBaseObject *pScreen, IGUIBaseObject *pParent, const string &sTypeName, IGUIBaseObject *&pWidget);
		bool CreateStyle(IGUIBaseObject *pScreen, const string &sTypeName, IGUIBaseObject *&pStyle);
		bool CreateScreen(const string &sTypeName, IGUIBaseObject *&pScreen);

		bool RegisterWidget(const string &sScreenType, const string &sTypeName, PCreateGUIObjectProc_t pProc);
		bool UnRegisterWidget(const string &sScreenType, const string &sTypeName);
		
		bool RegisterStyle(const string &sScreenType, const string &sTypeName, PCreateGUIObjectProc_t pProc);
		bool UnRegisterStyle(const string &sScreenType, const string &sTypeName);
		
		bool RegisterScreen(const string &sTypeName, PCreateGUIObjectProc_t pProc);
		bool UnRegisterScreen(const string &sTypeName);

		void Clear();
	};

//-------------------------------------------------------------------

}	// GUI
}	// Engine

#endif	// _UX_GUI_OBJECT_FACTORY_H
